﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Miris.HumanMilkAnalyser.DataModel;
using Miris.HumanMilkAnalyser.Service;
using Miris.HumanMilkAnalyser.WPF.Model;
using Miris.HumanMilkAnalyser.WPF.Shared;

namespace Miris.HumanMilkAnalyser.WPF.ViewModel.TestItemViewModel
{
    public class TestItemSingleViewModel : MyViewModelBase
    {
        protected IList<AnalysisItem> AnalysisItemList;
        protected MilkStage CurrentMilkStage;

        /// <summary>
        /// Initializes a new instance of the SingleTestItemViewModel class.
        /// </summary>
        public TestItemSingleViewModel(IDataService dataService, IList<AnalysisItem> analysisItemList, MilkStage milkStage)
            : base(dataService)
        {
            AnalysisItemList = analysisItemList;
            CurrentMilkStage = milkStage;

            InitializeParameters();
        }

        /// <summary>
        /// Initialize all necessary parameters.
        /// </summary>
        protected virtual void InitializeParameters()
        {
            TestResultUnit = "g/100ml";

            SetTestResultRangeValue();
            SetTestResultMinMaxValue();
        }

        /// <summary>
        /// Set RangeStartValue & RangeEndValue based on CurrentMilkStage.
        /// </summary>
        protected virtual void SetTestResultRangeValue() { }

        protected virtual void SetAnalysisItem()
        {
            var analysisItem = AnalysisItemList.Where(p => p.ItemName == TestItemName).FirstOrDefault();

            TestItemTitle = analysisItem.ItemTitle;
            TestItemUsage = analysisItem.ItemUsage;
            DietaryRecommendation = analysisItem.DietaryRecommendation;
        }

        /// <summary>
        /// Set MinValue & MaxValue based on CurrentMilkStage.
        /// </summary>
        protected virtual void SetTestResultMinMaxValue()
        {
            MinValue = 0;
        }

        /// <summary>
        /// Set the TestResultConclusion based on the test result.
        /// </summary>
        protected virtual void SetTestResultConclusion()
        {
            if (TestResult < RangeStartValue)
            {
                TestResultConclusion = "偏低";
            }
            else if (TestResult >= RangeStartValue && TestResult <= RangeEndValue)
            {
                TestResultConclusion = "正常";
            }
            else if (TestResult > RangeEndValue)
            {
                TestResultConclusion = "偏高";
            }
        }

        /// <summary>
        /// The <see cref="TestItemName" /> property's name.
        /// </summary>
        public const string TestItemNamePropertyName = "TestItemName";

        private string _testItemName = string.Empty;

        /// <summary>
        /// Sets and gets the TestItemName property.
        /// Changes to that property's value raise the PropertyChanged event. 
        /// </summary>
        public string TestItemName
        {
            get
            {
                return _testItemName;
            }

            set
            {
                if (_testItemName == value)
                {
                    return;
                }

                RaisePropertyChanging(TestItemNamePropertyName);
                _testItemName = value;
                RaisePropertyChanged(TestItemNamePropertyName);
            }
        }

        /// <summary>
        /// The <see cref="TestItemTitle" /> property's name.
        /// </summary>
        public const string TestItemTitlePropertyName = "TestItemTitle";

        private string _testItemTitle = string.Empty;

        /// <summary>
        /// Sets and gets the TestItemTitle property.
        /// Changes to that property's value raise the PropertyChanged event. 
        /// </summary>
        public string TestItemTitle
        {
            get
            {
                return _testItemTitle;
            }

            set
            {
                if (_testItemTitle == value)
                {
                    return;
                }

                RaisePropertyChanging(TestItemTitlePropertyName);
                _testItemTitle = value;
                RaisePropertyChanged(TestItemTitlePropertyName);
            }
        }

        /// <summary>
        /// The <see cref="ResultRawData" /> property's name.
        /// </summary>
        public const string ResultRawDataPropertyName = "ResultRawData";

        private string _resultRawData = string.Empty;

        /// <summary>
        /// Sets and gets the ResultRawData property.
        /// Changes to that property's value raise the PropertyChanged event. 
        /// </summary>
        public string ResultRawData
        {
            get
            {
                return _resultRawData;
            }

            set
            {
                if (_resultRawData == value)
                {
                    return;
                }

                RaisePropertyChanging(ResultRawDataPropertyName);
                _resultRawData = value;
                RaisePropertyChanged(ResultRawDataPropertyName);
            }
        }

        /// <summary>
        /// The <see cref="TestResultUnit" /> property's name.
        /// </summary>
        public const string TestResultUnitPropertyName = "TestResultUnit";

        private string _testResultUnit = string.Empty;

        /// <summary>
        /// Sets and gets the TestResultUnit property.
        /// Changes to that property's value raise the PropertyChanged event. 
        /// </summary>
        public string TestResultUnit
        {
            get
            {
                return _testResultUnit;
            }

            set
            {
                if (_testResultUnit == value)
                {
                    return;
                }

                RaisePropertyChanging(TestResultUnitPropertyName);
                _testResultUnit = value;
                RaisePropertyChanged(TestResultUnitPropertyName);
            }
        }

        /// <summary>
        /// The <see cref="TestResultConclusion" /> property's name.
        /// </summary>
        public const string TestResultConclusionPropertyName = "TestResultConclusion";

        private string _testResultConclusion = string.Empty;

        /// <summary>
        /// Sets and gets the TestResultConclusion property.
        /// Changes to that property's value raise the PropertyChanged event. 
        /// </summary>
        public string TestResultConclusion
        {
            get
            {
                return _testResultConclusion;
            }

            set
            {
                if (_testResultConclusion == value)
                {
                    return;
                }

                RaisePropertyChanging(TestResultConclusionPropertyName);
                _testResultConclusion = value;
                RaisePropertyChanged(TestResultConclusionPropertyName);
            }
        }

        /// <summary>
        /// The <see cref="TestItemUsage" /> property's name.
        /// </summary>
        public const string TestItemUsagePropertyName = "TestItemUsage";

        private string _testItemUsage = string.Empty;

        /// <summary>
        /// Sets and gets the TestItemUsage property.
        /// Changes to that property's value raise the PropertyChanged event. 
        /// </summary>
        public string TestItemUsage
        {
            get
            {
                return _testItemUsage;
            }

            set
            {
                if (_testItemUsage == value)
                {
                    return;
                }

                RaisePropertyChanging(TestItemUsagePropertyName);
                _testItemUsage = value;
                RaisePropertyChanged(TestItemUsagePropertyName);
            }
        }

        /// <summary>
        /// The <see cref="DietaryRecommendation" /> property's name.
        /// </summary>
        public const string DietaryRecommendationPropertyName = "DietaryRecommendation";

        private string _dietaryRecommendation = string.Empty;

        /// <summary>
        /// Sets and gets the DietaryRecommendation property.
        /// Changes to that property's value raise the PropertyChanged event. 
        /// </summary>
        public string DietaryRecommendation
        {
            get
            {
                return _dietaryRecommendation;
            }

            set
            {
                if (_dietaryRecommendation == value)
                {
                    return;
                }

                RaisePropertyChanging(DietaryRecommendationPropertyName);
                _dietaryRecommendation = value;
                RaisePropertyChanged(DietaryRecommendationPropertyName);
            }
        }

        /// <summary>
        /// The <see cref="TestResult" /> property's name.
        /// </summary>
        public const string TestResultPropertyName = "TestResult";

        private double _testResult = 0;

        /// <summary>
        /// Sets and gets the TestResult property.
        /// Changes to that property's value raise the PropertyChanged event. 
        /// </summary>
        public double TestResult
        {
            get
            {
                return _testResult;
            }

            set
            {
                if (_testResult == value)
                {
                    return;
                }

                RaisePropertyChanging(TestResultPropertyName);
                _testResult = value;
                RaisePropertyChanged(TestResultPropertyName);

                SetTestResultConclusion();
            }
        }

        /// <summary>
        /// The <see cref="ExtraInfo" /> property's name.
        /// </summary>
        public const string ExtraInfoPropertyName = "ExtraInfo";

        private string _extraInfo = string.Empty;

        /// <summary>
        /// Sets and gets the ExtraInfo property.
        /// Changes to that property's value raise the PropertyChanged event. 
        /// </summary>
        public string ExtraInfo
        {
            get
            {
                return _extraInfo;
            }

            set
            {
                if (_extraInfo == value)
                {
                    return;
                }

                RaisePropertyChanging(ExtraInfoPropertyName);
                _extraInfo = value;
                RaisePropertyChanged(ExtraInfoPropertyName);
            }
        }

        /// <summary>
        /// The <see cref="RangeStartValue" /> property's name.
        /// </summary>
        public const string RangeStartValuePropertyName = "RangeStartValue";

        private double _rangeStartValue = 0;

        /// <summary>
        /// Sets and gets the RangeStartValue property.
        /// Changes to that property's value raise the PropertyChanged event. 
        /// </summary>
        public double RangeStartValue
        {
            get
            {
                return _rangeStartValue;
            }

            set
            {
                if (_rangeStartValue == value)
                {
                    return;
                }

                RaisePropertyChanging(RangeStartValuePropertyName);
                _rangeStartValue = value;
                RaisePropertyChanged(RangeStartValuePropertyName);
            }
        }

        /// <summary>
        /// The <see cref="RangeEndValue" /> property's name.
        /// </summary>
        public const string RangeEndValuePropertyName = "RangeEndValue";

        private double _rangeEndValue = 0;

        /// <summary>
        /// Sets and gets the RangeEndValue property.
        /// Changes to that property's value raise the PropertyChanged event. 
        /// </summary>
        public double RangeEndValue
        {
            get
            {
                return _rangeEndValue;
            }

            set
            {
                if (_rangeEndValue == value)
                {
                    return;
                }

                RaisePropertyChanging(RangeEndValuePropertyName);
                _rangeEndValue = value;
                RaisePropertyChanged(RangeEndValuePropertyName);
            }
        }

        /// <summary>
        /// The <see cref="MaxValue" /> property's name.
        /// </summary>
        public const string MaxValuePropertyName = "MaxValue";

        private double _maxValue = 0;

        /// <summary>
        /// Sets and gets the MaxValue property.
        /// Changes to that property's value raise the PropertyChanged event. 
        /// </summary>
        public double MaxValue
        {
            get
            {
                return _maxValue;
            }

            set
            {
                if (_maxValue == value)
                {
                    return;
                }

                RaisePropertyChanging(MaxValuePropertyName);
                _maxValue = value;
                RaisePropertyChanged(MaxValuePropertyName);
            }
        }

        /// <summary>
        /// The <see cref="MinValue" /> property's name.
        /// </summary>
        public const string MinValuePropertyName = "MinValue";

        private double _minValue = 0;

        /// <summary>
        /// Sets and gets the MinValue property.
        /// Changes to that property's value raise the PropertyChanged event. 
        /// </summary>
        public double MinValue
        {
            get
            {
                return _minValue;
            }

            set
            {
                if (_minValue == value)
                {
                    return;
                }

                RaisePropertyChanging(MinValuePropertyName);
                _minValue = value;
                RaisePropertyChanged(MinValuePropertyName);
            }
        }
    }
}
